
#include <socket.h>
#include <connection.h>

struct RequestStatus {
  int64_t m_requestCnt;
  int64_t m_byteSend;
  int64_t m_byteRecv;

  RequestStatus() : m_requestCnt(0),
                    m_byteSend(0), m_byteRecv(0) {

  }

  void Report(const char *type) {
    printf("###%s: requestCnt:%ld\tSendBytes:%ld\tRecvBytes:%ld\n",
           type, m_requestCnt, m_byteSend, m_byteRecv);
  }
};

cr_local_var(RequestStatus, __stats);

void listenServer() {
  cr_go [] {
    ServerSocket *servSocket = new ServerSocket("127.0.0.1", 9090);
    servSocket->Listen();

    while (true) {
      Socket *cliSocket = servSocket->Accept();
      if (cliSocket == nullptr) {
        break;
      }
      cr_go [cliSocket, __stats] {
        char buf[32] = "\0";
        while (true) {
          memset(buf, '\0', sizeof(buf));
          uint32_t ret = cliSocket->Read((uint8_t *) buf, sizeof(buf));
          if (ret <= 0) {
            break;
          }

          __stats->m_byteRecv += ret;
          __stats->m_requestCnt += 1;

          printf("from client(%s:%d): %s\n", cliSocket->m_peerIp.c_str(), cliSocket->m_peerPort, buf);
          std::string rep = "hello world server!";
          ret = cliSocket->Write((const uint8_t *) rep.c_str(), rep.size());
          if (ret <= 0) {
            break;
          }

          __stats->m_byteSend += ret;
          __stats->Report("client uthread");
        }
        cliSocket->Close();
        delete cliSocket;
      };
    }
  };
  cr_scheduler();
}

void client() {
  for (int i = 0; i < 5; ++i) {
    cr_go [] {
      const int len = 32;
      char *buf = new char[len];
      sprintf(buf, "request:%d", 1);
      Socket *socket = new Socket("tcp://127.0.0.1:9090");

      socket->Open();

      int wRet = socket->Write((const uint8_t *) buf, strlen(buf));
      if (wRet > 0) {
        memset(buf, '\0', len);
        wRet = socket->Read((uint8_t *) buf, len);
        if (wRet > 0) {
          printf("from server(%s:%d): %s\n",
                 socket->m_peerIp.c_str(), socket->m_peerPort, buf);
        }
      }
      socket->Close();
      delete socket;
    };
  }

  cr_scheduler();
}


int main2(int argc, char **argv) {
  int pid = fork();
  if (pid > 0) {
    listenServer();
  } else {
    fork();
    sleep(2);
    printf("start call\n");
    client();
    printf("cli process exit!\n");
  }
}
